<template>
	<div class="h-full">
		<div class="flow-app">
			<div ref="refStencil" class="flow-wrap"></div>
			<div ref="refContainer" class="app-content" />
			<div class="app-interface">
				<n-button color="#8a2be2" @click="flowCheck">check </n-button>
			</div>
		</div>
		<TeleportContainer />
	</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { Graph } from "@antv/x6";
import { register, getTeleport } from "@antv/x6-vue-shape";
import { Stencil } from "@antv/x6-plugin-stencil";
import dayjs from "dayjs";
import StartTag from "./components/StartTag.vue";
import EndTag from "./components/EndTag.vue";
import { StepTag } from "./components";
register({
	shape: "start-node",
	width: 100,
	height: 100,
	component: StartTag,
	ports: {
		groups: {
			top: {
				position: "top",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 5,
					},
				},
			},
			bottom: {
				position: "bottom",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 5,
					},
				},
			},
		},
	},
});
register({
	shape: "end-node",
	width: 100,
	height: 100,
	component: EndTag,
	ports: {
		groups: {
			top: {
				position: "top",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 5,
					},
				},
			},
			bottom: {
				position: "bottom",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 5,
					},
				},
			},
		},
	},
});
register({
	shape: "step-node",
	width: 200,
	component: StepTag,
	ports: {
		groups: {
			top: {
				position: "top",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 2,
					},
				},
			},
			bottom: {
				position: "bottom",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 2,
						dy: -2,
					},
				},
			},
			left: {
				position: "left",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 2,
					},
				},
			},
			right: {
				position: "right",
				attrs: {
					circle: {
						magnet: true,
						stroke: "#8f8f8f",
						r: 2,
					},
				},
			},
		},
	},
});

const TeleportContainer = getTeleport();
const refStencil = ref<HTMLElement | null>(null);
const refContainer = ref<HTMLElement | null>(null);
let graph!: Graph;
let stencil!: Stencil;

const buildGraph = () => {
	graph = new Graph({
		container: refContainer.value,
		width: 800,
		height: 600,
		background: {
			color: "#F2F7FA",
		},
		connecting: {
			allowBlank: false,
			allowMulti: false,
			allowLoop: false,
			allowNode: true,
			allowEdge: false,
			allowPort: true,
			targetAnchor: {
				// 当连接到节点时，通过 targetAnchor 来指定目标节点的锚点。
				name: "top",
				args: {
					dx: 0,
				},
			},
			connectionPoint: "anchor",
			createEdge() {
				return this.createEdge({
					attrs: {
						line: {
							stroke: "#8f8f8f",
							strokeWidth: 1,
						},
					},
				});
			},
		},
	});
	graph.addNode({
		shape: "step-node",
		data: {
			processOperationName: "5300-00",
			description: "嘎嘎嘎",
		},
		x: 0,
		y: 0,
		width: 120,
		height: 40,
	});
	graph.centerContent();
	graph.on("node:added", ({ node }) => {
		const shape = node.shape;
		if (shape === "start-node" || shape === "end-node") {
			let contNum = 0;
			const nodes = graph.getNodes();
			nodes.forEach((existNode) => {
				if (existNode.shape === shape) {
					contNum += 1;
				}
			});
			if (contNum > 1) {
				node.remove();
			}
			node.addPort({
				group: shape === "start-node" ? "bottom" : "top",
			});
		}
		if (shape === "step-node") {
			const arrts = {
				data: {
					TimeKey: dayjs().format("YYYYMMDDHHmmssSSS") + dayjs().format("x"),
				},
			};
			node.setData({ processOperationName: "5500-00" });
			node.setAttrs(arrts);
			node.addPorts([
				{
					group: "top",
					args: {
						dy: 2,
					},
				},
				{
					group: "left",
					args: {
						dy: 5,
					},
				},
				{
					group: "right",
					args: {
						dy: 5,
					},
				},
				{
					group: "bottom",
					args: {
						dy: 8,
					},
				},
			]);
		}
	});
	graph.on("cell:mouseenter", ({ cell }) => {
		if (cell.isNode()) {
			cell.addTools([
				{
					name: "boundary",
					args: {
						attrs: {
							fill: "#7c68fc",
							stroke: "#333",
							"stroke-width": 1,
							"fill-opacity": 0.2,
						},
					},
				},
				{
					name: "button-remove",
					args: {
						x: 0,
						y: 0,
					},
				},
			]);
		} else {
			cell.addTools([
				"vertices",
				"segments",
				{
					name: "button-remove",
					args: {
						x: 0,
						y: 0,
					},
				},
			]);
		}
	});

	graph.on("cell:mouseleave", ({ cell }) => {
		cell.removeTools();
	});
};

const buildStencil = (): void => {
	stencil = new Stencil({
		target: graph,
		title: "工艺流程",
		search(cell, keyword) {
			if (keyword) {
				return (
					cell.shape === "step-node" &&
					cell.data.processOperationName.includes(keyword)
				);
			}
			return true;
		},
		groups: [
			{ name: "basic", title: "基础" },
			{
				name: "steps",
				title: "站点",
				collapsable: false,
				layoutOptions: {
					columns: 1,
					dx:60,
					rowHeight:'compact'
				},
			},
		],
		placeholder: "根据工艺站点名称查询",
		notFoundText: "Not Found",
		collapsable: true,
		stencilGraphHeight: 0,
	});
	refStencil.value.appendChild(stencil.container);
	const start = graph.createNode({
		shape: "start-node",
		x: 40,
		y: 40,
		width: 40,
		height: 40,
	});
	const end = graph.createNode({
		shape: "end-node",
		x: 40,
		y: 40,
		width: 40,
		height: 40,
	});
	const step = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5300-00",
			description: "嘎嘎嘎",
		},
		width: 180,
		height: 50,
	});
	const step1 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step2 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step3 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step4 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step5 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step6= graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step7 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号",
		},
		width: 180,
		height: 50,
	});
	const step8 = graph.createNode({
		shape: "step-node",
		data: {
			processOperationName: "5400-00",
			description: "呵呵二号大无畏的我的的",
		},
		width: 180,
		height: 50,
	});
	console.log(step);
	stencil.load([start, end], "basic");
	stencil.load([step,step1,step2,step3,step4,step5,step6,step7,step8], "steps");
};

const flowCheck = () => {
	const nodes = graph.getNodes();
	const startNode = nodes.filter((existNode) => {
		return existNode.shape === "start-node";
	})[0];
	console.log(startNode.shape);
	const flows = graph.getSuccessors(startNode);
	flows.forEach((flow) => {
		if (flow.shape === "step-node") {
			console.log(flow);
			console.log("TimeKey", flow.getAttrs().data.TimeKey);
		}
	});
};

onMounted(async () => {
	// await getAreaList();
	buildGraph();
	buildStencil();
});
</script>
<style scoped>
.flow-app {
	display: flex;
	padding: 0;
	font-family: sans-serif;

	.app-content {
		flex: 1;
		height: 100%;
		margin-right: 8px;
		margin-left: 8px;
		box-shadow: 0 0 10px 1px #e9e9e9;
	}

	.flow-wrap {
		position: relative;
		width: 220px;
		border: 1px solid #f0f0f0;
	}

	.app-interface {
		position: relative;
		width: 200px;
		border: 1px solid #f0f0f0;
	}
}
</style>
